import Core.Basic
from Core.package import *
import pathlib
import requests
from PIL import Image  # 新增：导入PIL库
import io  # 新增：导入io库


class Worker_Thread(QThread):
    thread_task_data = Signal(dict)
    Current_Download_Process = Signal(int)
    def __init__(self, parent = None):
        super().__init__(parent)
        self.task_data = dict()

    # 新增：图片格式转换方法
    def convert_image_to_jpg(self, image_data, save_path):
        """将图片数据转换为JPG格式并保存，保持原有功能逻辑"""
        try:
            with Image.open(io.BytesIO(image_data)) as img:
                # 处理透明通道
                if img.mode in ('RGBA', 'LA'):
                    background = Image.new(img.mode[:-1], img.size, (255, 255, 255))
                    background.paste(img, img.split()[-1])
                    img = background
                elif img.mode == 'P':
                    img = img.convert('RGB')
                
                img.save(save_path, 'JPEG', quality=95)
            return True
        except Exception as e:
            print(f"图片转换失败: {e}")
            # 转换失败时保存原始数据
            with open(save_path, 'wb') as f:
                f.write(image_data)
            return False
    
    def run(self):
        try:
            # 获取请求头
            driver = Core.Basic.GlobalVar.driver
            user_agent = driver.execute_script("return navigator.userAgent;")
            download_directory = pathlib.Path("./Data/Product_Download_File").absolute().resolve()
            
            
            # 统计所有需要进行下载的数量刻度
            DownloadCount = int(0)
            CurrentDownloadCount = int(0)
            for item in self.task_data['config_list']:                
                # 主图数量
                __main_image_counts = len(item['main_images_list'])
                __detail_image_counts = len(item['detail_images_url'])
                __sku_image_counts = len(item['sku_list'])
                
                if item['main_video_url']:
                    __video_count = 1
                else:
                    __video_count = 0
                
                DownloadCount += __main_image_counts
                DownloadCount += __detail_image_counts
                DownloadCount += __sku_image_counts
                DownloadCount += __video_count
            
            print(f"提示 : 统计的数量是 {DownloadCount}")
            
            # 迭代信息文件进行逐个下载
            for item in self.task_data['config_list']:
                item_save_directory_name = pathlib.Path(item['download_json_file_path']).absolute().resolve().stem
                item_mainimage_directory = pathlib.Path(download_directory).joinpath(item_save_directory_name).joinpath("主图")
                item_detailimage_directory =pathlib.Path(download_directory).joinpath(item_save_directory_name).joinpath("详情图")
                item_skuimage_directory =pathlib.Path(download_directory).joinpath(item_save_directory_name).joinpath("SKU")
                item_video_directory =pathlib.Path(download_directory).joinpath(item_save_directory_name).joinpath("视频")
                print(f"提示 : 正在下载 {item}")
                            
                # 1.下载主图图片
                for index,image_url in enumerate(item['main_images_list'],start=1):
                    print(f"提示 : 正在下载第 {index} 张主图图片...")
                    response = requests.get(url=image_url,headers={"User-Agent":user_agent})
                    savefilename = f"Main-{index:03d}.jpg"
                    item_mainimage_directory.mkdir(parents=True,exist_ok=True)
                    savepath = item_mainimage_directory.joinpath(savefilename)
                    
                    # 修改：使用转换方法替代直接写入
                    self.convert_image_to_jpg(response.content, savepath)
                    
                    CurrentDownloadCount += 1
                    self.Current_Download_Process.emit(int(CurrentDownloadCount/DownloadCount*100))            


                # 2.下载详情图片
                for index,image_url in enumerate(item['detail_images_url'],start=1):
                    print(f"提示 : 正在下载第 {index} 张详情图片...")
                    response = requests.get(url=image_url,headers={"User-Agent":user_agent})
                    savefilename = f"Detail-{index:03d}.jpg"
                    item_detailimage_directory.mkdir(parents=True,exist_ok=True)
                    savepath = item_detailimage_directory.joinpath(savefilename)
                    
                    # 修改：使用转换方法替代直接写入
                    self.convert_image_to_jpg(response.content, savepath)
                    
                    CurrentDownloadCount += 1
                    self.Current_Download_Process.emit(int(CurrentDownloadCount/DownloadCount*100))


                # 3.下载SKU图片
                for index,image_url in enumerate(item['sku_list'],start=1):
                    print(f"提示 : 正在下载第 {index} 张sku图片...")
                    print(image_url,'\n')
                    response = requests.get(url=image_url['sku_img_url'],headers={"User-Agent":user_agent})
                    savefilename = f"Sku_{index:03d}_{image_url['sku_label']}.jpg"
                    
                    item_skuimage_directory.mkdir(parents=True,exist_ok=True)
                    savepath = item_skuimage_directory.joinpath(savefilename)
                    
                    # 修改：使用转换方法替代直接写入
                    self.convert_image_to_jpg(response.content, savepath)
                    
                    CurrentDownloadCount += 1
                    self.Current_Download_Process.emit(int(CurrentDownloadCount/DownloadCount*100))

                # 4.下载视频
                if item['main_video_url']:
                    with requests.get(url=item['main_video_url'],headers={"User-Agent":user_agent},stream=True,timeout=5) as response:
                        # 检查请求是否成功
                        response.raise_for_status()
                        
                        # 打开文件准备写入
                        item_video_directory.mkdir(parents=True,exist_ok=True)
                        savepath = item_video_directory.joinpath("Main_Video.mp4")
                        
                        with open(savepath, 'wb') as file:
                            # 分块写入，每次读取 1024*1024 字节（1MB）
                            for chunk in response.iter_content(chunk_size=1024*1024):
                                if chunk:  # 确保 chunk 不是空的
                                    file.write(chunk)
                                    file.flush()  # 刷新缓冲区，立即写入磁盘

                        CurrentDownloadCount += 1
                        self.Current_Download_Process.emit(int(CurrentDownloadCount/DownloadCount*100))
                    
                

        except Exception as e:
            print(f"提示 : 员工线程任务发生错误!\n\
                    错误信息: {e}")
        finally:
            self.thread_task_data.emit(self.task_data)
        
        
    def __delattr__(self, name):
        print(f"提示 : 子任务子线程运行结束!正在销毁资源 {self}")
        return super().__delattr__(name)
    

class Staff_DownloadFile_All(QObject):
    Start_Task = Signal()   # 任务开始信号,启动任务时,请发送此信号
    Task_Finish = Signal()   # 任务完成信号,任务结束时候,请发送此信号
    Current_Completion_Process = Signal(int)
    Emergency_Stop = Signal()  # 紧急停止信号
    OnlyRun = Signal()  # 仅运行信号

    def __init__(self, parent=None):
        super().__init__(parent)
        self.Start_Task.connect(self.RunTask)
        
    @Slot(str)
    def slot_fun(self,text):
        print(f"我是槽函数,我是 {text}")

    # 设置员工属性
    def Set_Staff_Attribute(self,** kwargs):
        
        """设置员工对象的属性，用于后续任务执行
        """
        for key, value in kwargs.items():
            setattr(self, key, value)
        print(f"已设置属性: {kwargs.keys()}")

    def RunTask(self):

        # 获取需要操作的 主线程 窗口的 UI 对象
        self.parent_widget = self.parent()
        if self.parent_widget is None:
            print(f"提示 : 父对象为空!\n请将创建员工对象时,将父对象作为参数传入!")
            return
        # 获取 任务按钮 UI 控件对象
        self.task_button_object_name = "pushButton_all_download_product_data_file"
        self.task_button : QPushButton = self.parent().findChild(QPushButton,self.task_button_object_name)
        if self.task_button is None:
            print(f"提示 : 程序无法找到 {self.task_button_object_name} 对应的按钮!")
            print(f"提示 : 子任务结束!")
            return
        self.task_progressbar_object_name = "progressBar_download"
        self.task_progressbar : QProgressBar = self.parent().findChild(QProgressBar,self.task_progressbar_object_name)
        if self.task_progressbar is None:
            print(f"提示 : 程序无法找到 {self.task_progressbar_object_name} 对应的进度条!")
            print(f"提示 : 子任务结束!")
            return
        self.list_widget_object_name = "listWidget_configfile_list"
        self.list_widget : QListWidget = self.parent().findChild(QListWidget,self.list_widget_object_name)
        if self.list_widget is None:
            print(f"提示 : 获取 {self.list_widget_object_name} 对应的 listwidget 列表失败!")
            print(f"提示 : 子任务结束!")
            return



        # 创建子线程
        self.workerthread = Worker_Thread()
        self.workerthread.task_data['config_list'] = list()
        for index in range(self.list_widget.count()):
            config_file_name = self.list_widget.item(index).text()
            config_file_path = pathlib.Path("./Data/Product_Collection_ConfigFile").joinpath(config_file_name).absolute().resolve().__str__()
            try:
                single_config_data = json.load(fp=open(file=config_file_path,mode="r",encoding="utf-8"))
                single_config_data['download_json_file_path'] = config_file_path
                self.workerthread.task_data['config_list'].append(single_config_data)
            except:
                print(f"提示 : 读取解析文件 : \n\t{config_file_path} \n\t时发生错误,可能文件信息不正确,因此跳过对该文件进行下载操作!")
        
        


        # 绑定信号
        self.workerthread.finished.connect(lambda : QMessageBox.information(self.parent_widget,"提示","下载 [全部] 任务完成!"))
        self.workerthread.finished.connect(lambda : self.Task_Finish.emit())    # 子线程运行结束代表该员工类的任务结束
        self.workerthread.finished.connect(lambda : self.workerthread.quit())   # 线程结束，销毁线程
        self.workerthread.finished.connect(lambda : self.deleteLater())
        self.workerthread.finished.connect(lambda : self.task_button.setEnabled(True))
        
        self.workerthread.Current_Download_Process.connect(lambda count : self.task_progressbar.setValue(count))


        # 启动子线程,开始执行任务
        self.task_button.setEnabled(False)
        self.workerthread.start()
        


if __name__ == "__main__":
    import sys
    from PySide6.QtWidgets import QApplication
    app = QApplication(sys.argv)
    staff = Staff_DownloadFile_All(app)
    staff.RunTask()
    
    sys.exit(app.exec_())
